#pragma once
#include "dll_export.h"
#include <string>
#include <boost/serialization/serialization.hpp>

#ifndef LLDEBUG_MEMBER_NVP
#define LLDEBUG_MEMBER_NVP(name) boost::serialization::make_nvp(BOOST_STRINGIZE(name), BOOST_PP_CAT(m_, name))
#endif

LUA_DEBUG_BEGIN

/**
* @brief The type of the log message.
*/
enum LogType {
    LOGTYPE_MESSAGE, ///< Normal message.
    LOGTYPE_ERROR, ///< Error message.
    LOGTYPE_WARNING, ///< Warning message.
    LOGTYPE_TRACE, ///< Trace message.
};

/**
* @brief Log info that contains message and file infomation.
*/
class _LUAVM_API LogData
{
    LogType m_type;
    std::string m_message;
    std::string m_key;
    int m_line;
    bool m_isRemote;

private:
    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive& ar, const unsigned int) {
        ar & LLDEBUG_MEMBER_NVP(type);
        ar & LLDEBUG_MEMBER_NVP(message);
        ar & LLDEBUG_MEMBER_NVP(key);
        ar & LLDEBUG_MEMBER_NVP(line);
        ar & LLDEBUG_MEMBER_NVP(isRemote);
    }

public:
    explicit LogData(LogType type, const std::string &msg,
        const std::string &key=std::string(""), int line=-1);

    explicit LogData();

    ~LogData();

    /// Get the log type.
    LogType GetType() const {
        return m_type;
    }

    /// Get the log message.
    const std::string &GetLog() const {
        return m_message;
    }

    /// Get the source key that is associated with 'Source' class. It may be invalid.
    const std::string &GetKey() const {
        return m_key;
    }

    /// Get the source number. If it's invalid, it returns minus value.
    int GetLine() const {
        return m_line;
    }

    /// Was this log sent through the network ?
    bool IsRemote() const {
        return m_isRemote;
    }

    /// Set this the remote log.
    void SetRemote() {
        m_isRemote = true;
    }
};

LUA_DEBUG_END
